package com.bjbn.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bjbn.dto.BmsApiResponse;
import com.bjbn.dto.BmsDeviceGroupDto;
import com.bjbn.dto.BmsDeviceInfoDto;
import com.bjbn.dto.BmsDeviceValueDto;
import com.bjbn.entity.BmsDeviceGroup;
import com.bjbn.entity.BmsDeviceInfo;
import com.bjbn.entity.BmsDeviceValue;
import com.bjbn.entity.BmsDeviceValueHis;
import com.bjbn.entity.BmsDeviceValueThs;
import com.bjbn.entity.BmsDeviceValueThsHis;
import com.bjbn.entity.BmsDeviceValueLx;
import com.bjbn.entity.BmsDeviceValueLxHis;
import com.bjbn.mapper.BmsDeviceGroupMapper;
import com.bjbn.mapper.BmsDeviceInfoMapper;
import com.bjbn.mapper.BmsDeviceValueHisMapper;
import com.bjbn.mapper.BmsDeviceValueMapper;
import com.bjbn.mapper.BmsDeviceValueThsHisMapper;
import com.bjbn.mapper.BmsDeviceValueThsMapper;
import com.bjbn.mapper.BmsDeviceValueLxMapper;
import com.bjbn.mapper.BmsDeviceValueLxHisMapper;
import com.bjbn.service.BmsApiService;
import com.bjbn.service.BmsDataService;
import com.bjbn.service.ElasticsearchService;
import com.bjbn.entity.EsDeviceValueThs;
import com.bjbn.entity.EsDeviceValueLx;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * BMS数据服务实现类
 */
@Slf4j
@Service
public class BmsDataServiceImpl implements BmsDataService {

    @Value("${device.offline.threshold-minutes:10}")
    private int offlineThresholdMinutes;

    @Autowired
    private BmsApiService bmsApiService;

    /**
     * 初始化时输出配置信息
     */
    @javax.annotation.PostConstruct
    public void init() {
        log.info("BMS设备离线判断配置 - 时间阈值: {} 分钟", offlineThresholdMinutes);
    }

    @Autowired
    private BmsDeviceGroupMapper deviceGroupMapper;

    @Autowired
    private BmsDeviceInfoMapper deviceInfoMapper;

    @Autowired
    private BmsDeviceValueMapper deviceValueMapper;

    @Autowired
    private BmsDeviceValueHisMapper deviceValueHisMapper;

    @Autowired
    private BmsDeviceValueThsMapper deviceValueThsMapper;

    @Autowired
    private BmsDeviceValueThsHisMapper deviceValueThsHisMapper;

    @Autowired
    private BmsDeviceValueLxMapper deviceValueLxMapper;

    @Autowired
    private BmsDeviceValueLxHisMapper deviceValueLxHisMapper;

    @Autowired
    private ElasticsearchService elasticsearchService;

    @Override
    public void processDeviceGroupData() {
        log.info("开始处理设备分组数据");

        try {
            BmsApiResponse<List<BmsDeviceGroupDto>> response = bmsApiService.getAllDeviceList();
            if (response != null && response.getData() != null) {
                List<BmsDeviceGroupDto> deviceGroups = response.getData();
                log.info("获取到设备分组数据: {} 条", deviceGroups.size());

                for (BmsDeviceGroupDto dto : deviceGroups) {
                    try {
                        // 按照device_num为业务主键，插入更新
                        LambdaQueryWrapper<BmsDeviceGroup> wrapper = new LambdaQueryWrapper<>();
                        wrapper.eq(BmsDeviceGroup::getDeviceNum, dto.getDeviceNum());
                        BmsDeviceGroup existing = deviceGroupMapper.selectOne(wrapper);

                        if (existing == null) {
                            // 新增
                            BmsDeviceGroup entity = new BmsDeviceGroup();
                            BeanUtils.copyProperties(dto, entity);
                            entity.setCreateTime(new Date());
                            entity.setStatus("1");
                            entity.setDelFlag("0");
                            deviceGroupMapper.insert(entity);
                            log.info("新增设备分组: {}", dto.getDeviceNum());
                        } else {
                            // 更新
                            BeanUtils.copyProperties(dto, existing);
                            existing.setUpdateTime(new Date());
                            deviceGroupMapper.updateById(existing);
                            log.info("更新设备分组: {}", dto.getDeviceNum());
                        }
                    } catch (Exception e) {
                        log.error("处理设备分组数据异常，设备编码: {}", dto.getDeviceNum(), e);
                    }
                }
            } else {
                log.warn("获取设备分组数据失败");
            }
        } catch (Exception e) {
            log.error("处理设备分组数据异常", e);
        }
    }

    @Override
    public void processDeviceInfoData() {
        log.info("开始处理设备信息数据");

        try {
            // 获取所有设备分组
            List<BmsDeviceGroup> deviceGroups = deviceGroupMapper.selectList(null);
            log.info("获取到设备分组: {} 个", deviceGroups.size());

            for (BmsDeviceGroup deviceGroup : deviceGroups) {
                try {
                    BmsApiResponse<List<BmsDeviceInfoDto>> response = bmsApiService.getDeviceTagByDeviceId(deviceGroup.getDeviceNum());
                    if (response != null && response.getData() != null) {
                        List<BmsDeviceInfoDto> deviceInfos = response.getData();
                        log.info("设备 {} 获取到属性数据: {} 条", deviceGroup.getDeviceNum(), deviceInfos.size());

                        for (BmsDeviceInfoDto dto : deviceInfos) {
                            try {
                                // 按照device_num和tag_name为业务主键，插入更新
                                LambdaQueryWrapper<BmsDeviceInfo> wrapper = new LambdaQueryWrapper<>();
                                wrapper.eq(BmsDeviceInfo::getDeviceNum, dto.getDeviceId())
                                        .eq(BmsDeviceInfo::getTagName, dto.getTagName());
                                BmsDeviceInfo existing = deviceInfoMapper.selectOne(wrapper);

                                if (existing == null) {
                                    // 新增
                                    BmsDeviceInfo entity = new BmsDeviceInfo();
                                    entity.setDeviceNum(dto.getDeviceId());
                                    entity.setTagName(dto.getTagName());
                                    entity.setDeviceId(dto.getDeviceId());
                                    entity.setContactId(dto.getContactId());
                                    entity.setDeviceIp(dto.getDeviceIp());
                                    entity.setCreateTime(new Date());
                                    entity.setStatus("1");
                                    entity.setDelFlag("0");
                                    deviceInfoMapper.insert(entity);
                                    log.info("新增设备信息: {} - {}", dto.getDeviceId(), dto.getTagName());
                                } else {
                                    // 更新
                                    existing.setContactId(dto.getContactId());
                                    existing.setDeviceIp(dto.getDeviceIp());
                                    existing.setUpdateTime(new Date());
                                    deviceInfoMapper.updateById(existing);
                                    log.info("更新设备信息: {} - {}", dto.getDeviceId(), dto.getTagName());
                                }
                            } catch (Exception e) {
                                log.error("处理设备信息数据异常，设备: {} - {}", dto.getDeviceId(), dto.getTagName(), e);
                            }
                        }
                    } else {
                        log.warn("获取设备 {} 属性数据失败", deviceGroup.getDeviceNum());
                    }

                    // 避免请求过于频繁
                    Thread.sleep(100);
                } catch (Exception e) {
                    log.error("处理设备 {} 信息数据异常", deviceGroup.getDeviceNum(), e);
                }
            }
        } catch (Exception e) {
            log.error("处理设备信息数据异常", e);
        }
    }

    @Override
    public void processDeviceValueData() {
        log.info("开始处理设备采集值数据");

        try {
            // 获取所有设备分组
            List<BmsDeviceGroup> deviceGroups = deviceGroupMapper.selectList(null);
            log.info("获取到设备分组: {} 个", deviceGroups.size());

            for (BmsDeviceGroup deviceGroup : deviceGroups) {
                if ("电梯扶梯".equals(deviceGroup.getDeviceType()) || "步道梯".equals(deviceGroup.getDeviceType())) {
                    // 电梯扶梯和步道梯三分钟轮询一次
                    continue;
                }

                if ("无线温湿度采集器".equals(deviceGroup.getDeviceType()) || "无线光照度传感器".equals(deviceGroup.getDeviceType())) {
                    // 温湿度和照度也单独处理
                    continue;
                }

                try {
                    BmsApiResponse<BmsDeviceValueDto> response = bmsApiService.getDeviceValueByDeviceId(deviceGroup.getDeviceNum());
                    if (response != null && response.getData() != null) {
                        BmsDeviceValueDto dto = response.getData();
                        String deviceValueData = dto.getData();

                        if (StrUtil.isNotBlank(deviceValueData)) {

                            // 按照device_num为业务主键，插入更新设备采集值表（最新数据）
                            LambdaQueryWrapper<BmsDeviceValue> wrapper = new LambdaQueryWrapper<>();
                            wrapper.eq(BmsDeviceValue::getDeviceNum, deviceGroup.getDeviceNum());
                            BmsDeviceValue existing = deviceValueMapper.selectOne(wrapper);

                            if (existing == null) {
                                // 新增
                                BmsDeviceValue deviceValue = new BmsDeviceValue();
                                deviceValue.setDeviceNum(deviceGroup.getDeviceNum());
                                deviceValue.setDeviceValueData(deviceValueData);
                                deviceValue.setCreateTime(new Date());
                                deviceValue.setStatus("1");
                                deviceValue.setDelFlag("0");
                                deviceValue.setRecordTime(dto.getTime());
                                deviceValueMapper.insert(deviceValue);
                                // log.info("新增设备采集值: {}", deviceGroup.getDeviceNum());
                            } else {
                                // 更新
                                existing.setDeviceValueData(deviceValueData);
                                existing.setUpdateTime(new Date());
                                existing.setRecordTime(dto.getTime());
                                deviceValueMapper.updateById(existing);
                                //log.info("更新设备采集值: {}", deviceGroup.getDeviceNum());
                            }

                            log.info("获取到设备采集值: {}，设备类型：{}", deviceGroup.getDeviceNum(), deviceGroup.getDeviceType());

                            // 保存到历史数据表（每次都要插入）- 已注释，减轻服务器压力
                            // BmsDeviceValueHis deviceValueHis = new BmsDeviceValueHis();
                            // deviceValueHis.setDeviceNum(deviceGroup.getDeviceNum());
                            // deviceValueHis.setDeviceValueData(deviceValueData);
                            // deviceValueHis.setCreateTime(new Date());
                            // deviceValueHis.setRecordTime(dto.getTime());
                            // deviceValueHisMapper.insert(deviceValueHis);

                            /*
                            一体化空调
                            照明设备
                            电梯扶梯
                            多联机系统
                            多联机
                            无线温湿度采集器
                            光照采集器*/

                            // 根据设备类型进行特殊处理
                            /*
                            String deviceType = deviceGroup.getDeviceType();
                            if ("无线温湿度采集器".equals(deviceType)) {
                                processThsDeviceValue(deviceGroup.getDeviceNum(), dto);
                            } else if ("无线光照度传感器".equals(deviceType)) {
                                processLxDeviceValue(deviceGroup.getDeviceNum(), dto);
                            } else if ("一体化空调".equals(deviceType)) {
                                processAirConditionerDeviceValue(deviceGroup.getDeviceNum(), deviceValueData);
                            } else if ("照明设备".equals(deviceType)) {
                                processLightingDeviceValue(deviceGroup.getDeviceNum(), deviceValueData);
                            } else if ("电梯扶梯".equals(deviceType)) {
                                processElevatorDeviceValue(deviceGroup.getDeviceNum(), deviceValueData);
                            } else if ("多联机系统".equals(deviceType) || "多联机".equals(deviceType)) {
                                processMultiSplitDeviceValue(deviceGroup.getDeviceNum(), deviceValueData);
                            }*/
                        }
                    } else {
                        log.warn("获取设备 {} 采集值失败", deviceGroup.getDeviceNum());
                    }

                    // 避免请求过于频繁
                    Thread.sleep(100);
                } catch (Exception e) {
                    log.error("处理设备 {} 采集值数据异常", deviceGroup.getDeviceNum(), e);
                }
            }
        } catch (Exception e) {
            log.error("处理设备采集值数据异常", e);
        }
    }

    @Override
    public void processThsState() {
        log.info("开始处理设备（无线温湿度采集器）采集值数据");

        try {
            // 获取所有设备分组
            List<BmsDeviceGroup> deviceGroups = deviceGroupMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BmsDeviceGroup>()
                    .eq(BmsDeviceGroup::getDeviceType, "无线温湿度采集器"));

            for (BmsDeviceGroup deviceGroup : deviceGroups) {

                try {
                    BmsApiResponse<BmsDeviceValueDto> response = bmsApiService.getDeviceValueByDeviceId(deviceGroup.getDeviceNum());
                    if (response != null && response.getData() != null) {
                        BmsDeviceValueDto dto = response.getData();
                        String deviceValueData = dto.getData();

                        if (StrUtil.isNotBlank(deviceValueData)) {

                            // 按照device_num为业务主键，插入更新设备采集值表（最新数据）
                            LambdaQueryWrapper<BmsDeviceValue> wrapper = new LambdaQueryWrapper<>();
                            wrapper.eq(BmsDeviceValue::getDeviceNum, deviceGroup.getDeviceNum());
                            BmsDeviceValue existing = deviceValueMapper.selectOne(wrapper);

                            if (existing == null) {
                                // 新增
                                BmsDeviceValue deviceValue = new BmsDeviceValue();
                                deviceValue.setDeviceNum(deviceGroup.getDeviceNum());
                                deviceValue.setDeviceValueData(deviceValueData);
                                deviceValue.setCreateTime(new Date());
                                deviceValue.setStatus("1");
                                deviceValue.setDelFlag("0");
                                deviceValue.setRecordTime(dto.getTime());
                                deviceValueMapper.insert(deviceValue);
                            } else {
                                // 更新
                                existing.setDeviceValueData(deviceValueData);
                                existing.setUpdateTime(new Date());
                                existing.setRecordTime(dto.getTime());
                                deviceValueMapper.updateById(existing);
                            }

                            log.info("获取到设备采集值: {}，设备类型：{}", deviceGroup.getDeviceNum(), deviceGroup.getDeviceType());

                            processThsDeviceValue(deviceGroup.getDeviceNum(), dto);
                        }
                    } else {
                        log.warn("获取设备 {} 采集值失败", deviceGroup.getDeviceNum());
                    }

                    // 避免请求过于频繁
                    Thread.sleep(100);
                } catch (Exception e) {
                    log.error("处理设备 {} 采集值数据异常", deviceGroup.getDeviceNum(), e);
                }
            }
        } catch (Exception e) {
            log.error("处理设备采集值数据异常", e);
        }
    }

    @Override
    public void processLxState() {
        log.info("开始处理设备（无线光照度传感器）采集值数据");

        try {
            // 获取所有设备分组
            List<BmsDeviceGroup> deviceGroups = deviceGroupMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BmsDeviceGroup>()
                    .eq(BmsDeviceGroup::getDeviceType, "无线光照度传感器"));

            for (BmsDeviceGroup deviceGroup : deviceGroups) {

                try {
                    BmsApiResponse<BmsDeviceValueDto> response = bmsApiService.getDeviceValueByDeviceId(deviceGroup.getDeviceNum());
                    if (response != null && response.getData() != null) {
                        BmsDeviceValueDto dto = response.getData();
                        String deviceValueData = dto.getData();

                        if (StrUtil.isNotBlank(deviceValueData)) {

                            // 按照device_num为业务主键，插入更新设备采集值表（最新数据）
                            LambdaQueryWrapper<BmsDeviceValue> wrapper = new LambdaQueryWrapper<>();
                            wrapper.eq(BmsDeviceValue::getDeviceNum, deviceGroup.getDeviceNum());
                            BmsDeviceValue existing = deviceValueMapper.selectOne(wrapper);

                            if (existing == null) {
                                // 新增
                                BmsDeviceValue deviceValue = new BmsDeviceValue();
                                deviceValue.setDeviceNum(deviceGroup.getDeviceNum());
                                deviceValue.setDeviceValueData(deviceValueData);
                                deviceValue.setCreateTime(new Date());
                                deviceValue.setStatus("1");
                                deviceValue.setDelFlag("0");
                                deviceValue.setRecordTime(dto.getTime());
                                deviceValueMapper.insert(deviceValue);
                            } else {
                                // 更新
                                existing.setDeviceValueData(deviceValueData);
                                existing.setUpdateTime(new Date());
                                existing.setRecordTime(dto.getTime());
                                deviceValueMapper.updateById(existing);
                            }

                            log.info("获取到设备采集值: {}，设备类型：{}", deviceGroup.getDeviceNum(), deviceGroup.getDeviceType());

                            processLxDeviceValue(deviceGroup.getDeviceNum(), dto);
                        }
                    } else {
                        log.warn("获取设备 {} 采集值失败", deviceGroup.getDeviceNum());
                    }

                    // 避免请求过于频繁
                    Thread.sleep(100);
                } catch (Exception e) {
                    log.error("处理设备 {} 采集值数据异常", deviceGroup.getDeviceNum(), e);
                }
            }
        } catch (Exception e) {
            log.error("处理设备采集值数据异常", e);
        }
    }


    /**
     * 处理温湿度传感器数据
     */
    private void processThsDeviceValue(String deviceNum, BmsDeviceValueDto dto) {
        try {
            String deviceValueData = dto.getData();
            Map<String, Object> dataMap = JSON.parseObject(deviceValueData, Map.class);

            // 先删除旧的最新数据
            LambdaQueryWrapper<BmsDeviceValueThs> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(BmsDeviceValueThs::getDeviceNum, deviceNum);
            deviceValueThsMapper.delete(deleteWrapper);

            // 保存新的最新数据
            BmsDeviceValueThs ths = new BmsDeviceValueThs();
            ths.setDeviceNum(deviceNum);
            ths.setDeviceValueData(deviceValueData);
            ths.setCreateTime(new Date());
            ths.setRecordTime(dto.getTime());

            // 解析温湿度数据
            if (dataMap.containsKey("voltageValue")) {
                ths.setVoltageValue(Integer.valueOf(dataMap.get("voltageValue").toString()));
            }
            if (dataMap.containsKey("detachStatus")) {
                ths.setDetachStatus(dataMap.get("detachStatus").toString());
            }
            if (dataMap.containsKey("temperature")) {
                ths.setTemperature(dataMap.get("temperature").toString());
            }
            if (dataMap.containsKey("voltageStatus")) {
                ths.setVoltageStatus(dataMap.get("voltageStatus").toString());
            }
            if (dataMap.containsKey("humidness")) {
                ths.setHumidness(dataMap.get("humidness").toString());
            }

            // 判断设备在线/离线状态
            String offlineStatus = calculateOfflineStatus(dto.getTime());
            ths.setOffline(offlineStatus);

            deviceValueThsMapper.insert(ths);

            // 保存到历史数据表
            BmsDeviceValueThsHis thsHis = new BmsDeviceValueThsHis();
            BeanUtils.copyProperties(ths, thsHis);
            thsHis.setId(null); // 清除ID，让数据库自动生成
            deviceValueThsHisMapper.insert(thsHis);

            // 保存到Elasticsearch
            try {
                EsDeviceValueThs esThs = new EsDeviceValueThs();
                BeanUtils.copyProperties(ths, esThs);
                boolean esResult = elasticsearchService.saveThsData(esThs);
                if (esResult) {
                    log.info("成功保存温湿度传感器数据到ES: {}", deviceNum);
                } else {
                    log.warn("保存温湿度传感器数据到ES失败: {}", deviceNum);
                }
            } catch (Exception e) {
                log.error("保存温湿度传感器数据到ES异常，设备: {}", deviceNum, e);
            }

            log.info("保存温湿度传感器数据: {}，离线状态: {}", deviceNum, offlineStatus);
        } catch (Exception e) {
            log.error("处理温湿度传感器数据异常，设备: {}", deviceNum, e);
        }
    }

    /**
     * 处理光照采集器
     */
    private void processLxDeviceValue(String deviceNum, BmsDeviceValueDto dto) {
        try {
            String deviceValueData = dto.getData();
            Map<String, Object> dataMap = JSON.parseObject(deviceValueData, Map.class);

            // 先删除旧的最新数据
            LambdaQueryWrapper<BmsDeviceValueLx> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(BmsDeviceValueLx::getDeviceNum, deviceNum);
            deviceValueLxMapper.delete(deleteWrapper);

            // 保存新的最新数据
            BmsDeviceValueLx lx = new BmsDeviceValueLx();
            lx.setDeviceNum(deviceNum);
            lx.setDeviceValueData(deviceValueData);
            lx.setCreateTime(new Date());
            lx.setRecordTime(dto.getTime());

            // 解析照度数据
            if (dataMap.containsKey("illuminance")) {
                lx.setLxValue(Integer.valueOf(dataMap.get("illuminance").toString().replace("LUX", "")));
            }

            // 判断设备在线/离线状态
            String offlineStatus = calculateOfflineStatus(dto.getTime());
            lx.setOffline(offlineStatus);

            deviceValueLxMapper.insert(lx);

            // 保存到历史数据表
            BmsDeviceValueLxHis lxHis = new BmsDeviceValueLxHis();
            BeanUtils.copyProperties(lx, lxHis);
            lxHis.setId(null); // 清除ID，让数据库自动生成
            deviceValueLxHisMapper.insert(lxHis);

            // 保存到Elasticsearch
            try {
                EsDeviceValueLx esLx = new EsDeviceValueLx();
                BeanUtils.copyProperties(lx, esLx);
                boolean esResult = elasticsearchService.saveLxData(esLx);
                if (esResult) {
                    log.info("成功保存照度传感器数据到ES: {}", deviceNum);
                } else {
                    log.warn("保存照度传感器数据到ES失败: {}", deviceNum);
                }
            } catch (Exception e) {
                log.error("保存照度传感器数据到ES异常，设备: {}", deviceNum, e);
            }

            log.info("保存照度传感器数据: {}，离线状态: {}", deviceNum, offlineStatus);
        } catch (Exception e) {
            log.error("处理照度传感器数据异常，设备: {}", deviceNum, e);
        }
    }

    /**
     * 计算设备在线/离线状态
     *
     * @param recordTime 设备记录时间
     * @return 00-在线，01-离线
     */
    private String calculateOfflineStatus(Date recordTime) {
        if (recordTime == null) {
            // 如果记录时间为空，认为离线
            return "01";
        }

        Date currentTime = new Date();
        long timeDiff = currentTime.getTime() - recordTime.getTime();
        // 转换为分钟
        long minutesDiff = timeDiff / (1000 * 60);

        // 如果时间差超过配置的阈值，认为设备离线
        if (minutesDiff > offlineThresholdMinutes) {
            log.debug("设备离线判断 - 时间差: {} 分钟，阈值: {} 分钟，状态: 离线", minutesDiff, offlineThresholdMinutes);
            // 离线
            return "01";
        } else {
            log.debug("设备离线判断 - 时间差: {} 分钟，阈值: {} 分钟，状态: 在线", minutesDiff, offlineThresholdMinutes);
            // 在线
            return "00";
        }
    }

} 